package com.project.controller;

import com.project.entity.po.Member;
import com.project.exception.ControllerException;
import com.project.entity.qo.MemberQo;
import com.project.entity.qo.UserQo;
import com.project.result.ResponseResult;
import com.project.result.ResultCode;
import com.project.service.MsgService;
import com.project.service.UserService;
import com.project.utils.ShiroUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import java.io.Serializable;
import java.util.Date;

/**
 * @ProjectName:
 * @Package:
 * @ClassName:
 * @Author: ZhaoLongShi
 * @CreateDate:
 */
@SuppressWarnings("all")
@RestController
@RequestMapping("/user")
@Validated
public class UserController {

    @Resource
    private UserService userService;

    @Resource
    private MsgService msgService;

    @Resource
    private ValueOperations<String, Object> valueOperations;

    @Resource
    private RedisTemplate redisTemplate;
    /**
     * 登录
     *
     * @param userQo
     * @return
     */
    @PostMapping("/login")
    public ResponseResult<Serializable> login(@RequestBody UserQo userQo) {
        String newPassword = null;
        newPassword = ShiroUtils.sha256(userQo.getPassword(), null);
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(userQo.getUsername(),
                newPassword);
        try {
            SecurityUtils.getSubject().login(usernamePasswordToken);
        } catch (UnknownAccountException | IncorrectCredentialsException ua) {
            throw new ControllerException(ResultCode.ACCOUNT_LOGIN_ERROR);
        } catch (LockedAccountException lae) {
            throw new ControllerException(ResultCode.UN_AUTH);
        } catch (Exception e) {
            throw new ControllerException(ResultCode.SYSTEM_ERROR);
        }
        Serializable id = ShiroUtils.getSession().getId();
        valueOperations.set("sessionId", id);
        return ResponseResult.success(id);
    }

    /**
     * 手机号登录
     *
     * @param phone
     * @param code
     * @return
     */
    @GetMapping("/login/phone")
    public ResponseResult<Serializable> login(String phone, String code) {
        Serializable login = userService.login(phone, code);
        return ResponseResult.success(login);
    }

    @PostMapping("/logout")
    public ResponseResult<ResultCode> logout() {
        ShiroUtils.logout();
        redisTemplate.delete("sessionId");
        return ResponseResult.success(ResultCode.SUCCESS);
    }

    /**
     * 发送验证码
     *
     * @param phone
     * @return
     */
    @GetMapping("/msg")
    public ResponseResult<String> getCode(String phone) {
        String s = msgService.sendMsg(phone);
        return ResponseResult.success(s);
    }

    /**
     * 注册
     *
     * @param userQo
     * @return
     */
    @PutMapping("/register")
    public ResponseResult register(@RequestBody @Validated(UserQo.Add.class) UserQo userQo) {
        //加密
        String sha256 = ShiroUtils.sha256(userQo.getPassword(), null);
        userQo.setPassword(sha256);
        return ResponseResult.success(ResultCode.SUCCESS, userService.register(userQo));
    }

    /**
     * 更新用户信息
     *
     * @param userQo
     * @return
     */
    @PostMapping("/update/user")
    public ResponseResult updateUser(@RequestBody @Validated(UserQo.Update.class) UserQo userQo) {
        return ResponseResult.success(ResultCode.SUCCESS, userService.updateUserById(userQo));
    }

    /**
     * 修改密码
     *
     * @param oldPassword
     * @param newPassword
     * @return
     */
    @PutMapping("/update/password")
    public ResponseResult updatePassword(@NotNull
          String oldPassword,@NotNull  String newPassword) {
        ResponseResult result = userService.updatePasswordById(oldPassword,
                newPassword);
        return result;
    }

    /**
     * 注册成为VIP
     *
     * @param memberQo
     * @return
     */
    @PostMapping("/register/vip")
    public ResponseResult registerVip(@RequestBody MemberQo memberQo) {
        ResponseResult result = userService.registerVip(memberQo);
        return result;
    }

    /**
     * 根据用户ID查询会员信息
     *
     * @return
     */
    @GetMapping("select/member")
    public ResponseResult<Member> selectMemberInfoByUserId() {
        ResponseResult result = userService.selectMemberInfoByUserId();
        return result;
    }

    /**
     * 第三方充值会员
     *
     * @param price
     * @return
     */
    @PostMapping("/recharge/othor")
    public ResponseResult rechargeWithOthor(double price, String rechargeType) {
        ResponseResult result = userService.rechargeWithOthor(price, rechargeType);
        return result;
    }

    /**
     * 用余额充值会员
     *
     * @param price
     * @return
     */
    @PostMapping("/recharge/balance")
    public ResponseResult rechargeWithBalance(double price) {
        ResponseResult result = userService.rechargeWithBalance(price);
        return result;
    }

    /**
     * 充值到余额
     *
     * @param price
     * @return
     */
    @PostMapping("/rechrge/to/balance")
    public ResponseResult rechargeToBalance(double price) {
        ResponseResult result = userService.rechargeToBalance(price);
        return result;
    }

    /**
     * 获取会员充值记录
     *
     * @return
     */
    @GetMapping("/select/record")
    public ResponseResult selectRecordByUserId() {
        ResponseResult result = userService.selectRecordByUserId();
        return result;
    }

    /**
     * 没登录时访问
     *
     * @return
     */
    @GetMapping("/no/login")
    public ResponseResult<String> noLogin() {
        return ResponseResult.error(ResultCode.ACCOUNT_NOT_LOGIN);
    }

    /**
     * 上传图片
     *
     * @param file
     * @return
     */
    @GetMapping("/upload")
    public ResponseResult<String> upload(MultipartFile file) {
        String url = userService.upload(file);
        return ResponseResult.success(url);
    }


}
